import datetime

from django.db import transaction
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver

from social.user.models import UserLike, UserCallData, AVCallSetting
from social.user.tasks import update_user_follow_count, update_user_fans_count, update_user_friend_count, \
    send_new_fans_message


@receiver(post_save, sender=UserLike)
def user_like_post_save(sender, instance: UserLike, created, **kwargs):
    if created:
        transaction.on_commit(lambda: update_user_follow_count.delay(instance.from_user_id))
        transaction.on_commit(lambda: update_user_fans_count.delay(instance.to_user_id))
        transaction.on_commit(lambda: send_new_fans_message.delay(instance.id))
    else:
        update_fields = kwargs.get('update_fields', set())
        if update_fields and 'is_friend' in update_fields:
            transaction.on_commit(lambda: update_user_friend_count.delay(instance.from_user_id))


@receiver(post_delete, sender=UserLike)
def user_like_post_delete(sender, instance: UserLike, **kwargs):
    transaction.on_commit(lambda: update_user_follow_count.delay(instance.from_user_id))
    transaction.on_commit(lambda: update_user_fans_count.delay(instance.to_user_id))
    if instance.is_friend:
        transaction.on_commit(lambda: update_user_friend_count.delay(instance.from_user_id))


@receiver(post_save, sender=UserCallData)
def user_call_data_post_save(sender, instance: UserCallData, updated_fields=None, **kwargs):
    now = datetime.datetime.now()
    if updated_fields and 'call_duration' in updated_fields and instance.week == UserCallData.key_week(now):
        call_setting, created = AVCallSetting.objects.get_or_create(user=instance.user)
        if instance.call_level > call_setting.this_week_level:
            call_setting.video_level = instance.call_level
            call_setting.save(update_fields=['this_week_level'])
